6 generated chapters from the reviewed repository snapshot
Source: blue-az/TennisOracle:main@37b914d212a7dbdec3d4dff11a1b97eac7dfd3cd
This matters because it is the part of the product that turns a live tennis session into local shot history the owner can judge. TennisOracle Shot Capture is a local three-device system, not a cloud service: the player captures on the Watch, the operator keeps the iPhone relay and Mac backend running, and the Mac side turns incoming shot batches into local session history and feedback.
This matters because it is the part of the product that turns a live tennis session into local shot history the owner can judge. TennisOracle Shot Capture is a local three-device system, not a cloud service: the player captures on the Watch, the operator keeps the iPhone relay and Mac backend running, and the Mac side turns incoming shot batches into local session history and feedback. The owner should read it as a local-first research system whose core path is visible on the Watch and whose secondary boundaries are permissions, local history, and the documented Zepp calibration path. The supplied evidence does not settle whether the product is mainly for live feedback, post-session logging, calibration, or a mix, so this chapter keeps that decision open.
The simplest way to picture the product is as a chain with three roles around it. The player wears the Watch and uses the product's native capture modes, strokes and serve. The operator keeps the iPhone relay and Mac backend alive. The owner is the reader who has to decide what the product is mainly for, because the evidence does not settle whether live feedback, post-session logging, calibration research, or a mix is the true center.
The Watch is the front door of the product. The iPhone is a relay, not the main logic. The Mac backend is where local history and shot records become visible. Permissions, local history, and Zepp linkage matter because they can block or reinterpret the core path, but they do not replace it.
Figure: The product has a clear operating chain, but the owner question sits above it. That means the manual can explain who handles capture, relay, and history without pretending the product's main purpose has already been settled.
flowchart TD
O[Owner]
P[Player]
R[Operator]
W[Watch capture]
I[iPhone relay]
M[Mac history]
H[Local shot history]
O -.->|decides what the product is mainly for| C[Capture chain]
P -->|captures shots on| W
R -->|keeps alive| I
W -->|sends batches through| I
I -->|forwards batches to| M
M -->|turns batches into| H
The owner sits above a three-device capture chain. The player captures shots on the Watch, the operator keeps the iPhone relay alive, and the Mac turns incoming batches into local shot history. The consequence is that the product is understandable as a local chain, while the owner still has to decide what outcome the product is primarily for.
A supported run starts on the Watch. The player chooses a mode, starts capture, and the Watch begins collecting motion and producing live feedback. That data goes to the iPhone relay, which shows connection state and forwards batches over a fixed local network path to the Mac backend. The Mac backend turns incoming batches into shot records and session feedback.
That chain is fragile in the places an owner cares about. Supported capture depends on the Watch's health and workout permissions, and the source does not establish a graceful denial path. If the relay drops, the current batch can be lost rather than queued. If the backend reconnects, the live session view starts fresh instead of recovering durable history. The readiness number shown back to the player is derived feedback, not a measured physiology signal.
Figure: The intended chain is not the same as the protected boundary. Because the Mac side is reachable beyond the Watch and iPhone pair, network reachability matters before the session history should be treated as trusted.
flowchart LR
subgraph T[ Intended path ]
W[Watch]
I[iPhone relay]
M[Mac backend]
W --> I --> M
end
X[Other reachable client]
X -.->|can also reach the Mac side| M
The intended path runs from the Watch to the iPhone relay and then to the Mac backend. A separate reachable client can also reach the Mac side, so the real boundary is not the device chain by itself. The consequence is that the owner should treat network reachability as part of trust, not just device identity.
What is genuinely strong here is the shape of the system. It is easy to name the core chain, easy to separate the player and operator roles, and easy to see that the Watch is the main surface rather than a hidden backend concern. The iPhone gives the operator connection state instead of burying the relay. The documented Zepp path also stays visibly separate, which helps the owner keep calibration from swallowing the capture story.
Those strengths do not erase the trust boundary or recovery gaps. They just mean the product is understandable at a glance, which is a real advantage when the owner has to decide what to keep, what to fix, and what to verify next.
What happens: The Mac backend will accept any reachable client, not just the Watch and iPhone pair.
Why it matters: If that network path is reachable outside the intended devices, shot records and session events are not protected by the boundary shown in this snapshot.
What to do: Decide whether the backend needs device binding or another gate before you treat its session history as trusted.
Revisit when: When product frame behavior or related owner decisions change.
What happens: A relay failure can discard a batch instead of saving it for resend.
Why it matters: A short network failure can turn into missing capture data, not just a temporary pause.
What to do: Choose whether unsent batches should be buffered and replayed, or document the loss plainly for operators.
Revisit when: When product frame behavior or related owner decisions change.
What happens: After reconnect, the backend shows a new live session view rather than durable history.
Why it matters: An interrupted run may not read back as one continuous session, which affects how the owner interprets recovery.
What to do: Decide whether reconnect should resume the prior session or intentionally create a new one, then make the manual match that choice.
Revisit when: When product frame behavior or related owner decisions change.
What happens: The runtime uses UTC for session tags, while the linkage notes expect local date.
Why it matters: Crossing late evening sessions or day edges can split or mislabel history.
What to do: Pick one day-boundary rule for session tags and linked sessions, then align the runtime and the manual to it.
Revisit when: When product frame behavior or related owner decisions change.
Why it matters: The opening chapter and the later chapter order change if one of those is primary.
Revisit when: Before changing the related product frame behavior.
Why it matters: The iPhone relay currently reads like a fixed local-network bridge, and setup guidance depends on whether that stays true.
Revisit when: Before changing the related product frame behavior.
Why it matters: The snapshot proves a documented manual workflow, but not a live first-party surface.
Revisit when: Before changing the related product frame behavior.
Evidence boundary — Reviewed:
Not reviewed:
Re-run the Watch-to-iPhone-to-Mac flow on the intended devices, then check three things in the real session: whether missing permissions block capture the way you expect, whether a dropped relay loses data or preserves it for resend, and whether reconnect and day boundaries behave the way the manual says they should. If Zepp still matters, verify whether it is a live operator path or only a documented calibration procedure.
Reviewed: Reviewed repository snapshot, Founder/owner context
Not reviewed: External runtime and integrations, Unreviewed runtime and owner context
The capture session is one local chain: the player starts on the Apple Watch, chooses strokes or serve, and stops the run from the Watch while the iPhone forwards watch batches to the Mac backend. The player sees live speed, readiness, contact, and haptic feedback during the run, so this chapter is about the felt session loop, not three separate apps.
The capture session is one local chain: the player starts on the Apple Watch, chooses strokes or serve, and stops the run from the Watch while the iPhone forwards watch batches to the Mac backend. The player sees live speed, readiness, contact, and haptic feedback during the run, so this chapter is about the felt session loop, not three separate apps.
Some results may persist locally for later review, but the reviewed evidence does not settle whether the product’s primary supported outcome is live feedback, post-session logging, calibration work, or some mix. Later chapters own setup, signal meaning, history, and recovery.
Figure: The owner should read the session as one local loop: the Watch starts and stops capture, the iPhone carries batches, the Mac turns them into shot feedback, and the live feedback comes back while the same run is still active.
flowchart LR
P[Player on Watch]
I[iPhone relay]
M[Shot feedback on Mac]
L[Live feedback on Watch]
P --> I --> M --> L --> P
The diagram shows the player on the Watch starting the run, the iPhone relaying batches, the Mac turning those batches into shot feedback, and live feedback returning to the Watch. The consequence is that the session should be understood as one connected local loop, not as three separate products.
This chapter is the owner-facing picture of a single session. The player is not moving between unrelated tools; they start capture on the Watch, the iPhone acts as the relay surface, and the Mac backend turns incoming batches into shot feedback. That is why the owner should read the session as one local chain and not as three independent products.
Modes matter here because the Watch lets the player choose between strokes and serve before starting the run. The Watch also shows live speed, readiness, contact, and haptic feedback, but the meaning of those numbers still needs care: readiness is derived feedback, not a validated performance claim. Permission and network prerequisites belong in the setup chapter; this one stays on the runtime loop.
A normal session begins on the Watch. The player selects strokes or serve, then starts Oracle. The Watch collects motion and workout data, shows the live session feedback, and can stop the run from the same surface.
The iPhone is the relay surface. It shows backend connection status and batch count, and it forwards watch batch messages to the Mac over a fixed local-network websocket. If the connection drops, failed sends are not queued; the operator has to recover the relay instead of expecting automatic replay.
On the Mac, incoming batches become shot feedback events and local shot records. That output is useful for the session story, but it is not the same as a validated performance measure. A reconnect also does not pick up a durable historical view; it starts a fresh live session state.
Figure: Continuity is fragile at this boundary: a dropped relay batch is gone, a reconnect opens a fresh live session, and any reachable client can still reach the Mac path unless something else blocks it.
flowchart TD
W[Watch batches]
I[iPhone relay]
M[Mac shot path]
C[Any reachable client]
R[Reconnect]
F[Fresh live session]
X[Lost batch]
W --> I --> M
I -. dropped relay .-> X
C --> M
M --> R --> F
The diagram shows Watch batches going to the iPhone relay and then to the Mac shot path. It also shows a dropped relay leading to a lost batch, any reachable client reaching the Mac path, and a reconnect leading to a fresh live session. The consequence is that a relay break can erase work and the Mac entry point can weaken trust in session records.
Figure: Owners should treat Zepp as calibration-only evidence in this snapshot; the reviewed material does not justify presenting a confirmed live first-party Zepp surface.
flowchart LR
Z[Zepp in this snapshot]
D[Documented calibration workflow]
L[Live first-party surface]
S[Shown in the reviewed notes]
U[Not established here]
Z --> D
Z --> L
D --> S
L --> U
The diagram compares two readings of Zepp: a documented calibration workflow that appears in the reviewed material, and a live first-party surface that is not established here. The consequence is that the manual should stay calibration-only until a live path is confirmed.
The product gives the owner a clear, local story to explain: one capture screen on the Watch, one relay surface on the iPhone, and one detection surface on the Mac. That makes the session easier to describe to a player or operator without teaching implementation details.
The session also gives immediate visible feedback. The player can see mode choice, live metrics, and haptics on the Watch, while the iPhone shows relay state. That clarity is useful, even though the reviewed evidence also shows that some numbers are derived feedback and that the live session can still lose continuity when connectivity drops or the backend reconnects.
What happens: Shot writes are not idempotent, so repeated emission or an alternate path can create duplicate rows.
Why it matters: Later review can overstate how many shots happened in a session, which weakens trust in the history.
What to do: Add a dedupe rule or a replay-safe write policy before presenting shot counts as durable history.
Revisit when: When capture session behavior or related owner decisions change.
What happens: The readiness number in the shot path is generated from a synthetic input, even though the Watch presents it like a live score.
Why it matters: Owners could mistake a derived hint for a validated performance measure and make the wrong product or coaching decision.
What to do: Label readiness as derived session feedback unless calibration validation is added.
Revisit when: When capture session behavior or related owner decisions change.
Why it matters: The reviewed evidence confirms the permission boundary, but not the denial experience, so the manual cannot promise a specific failure state yet.
Revisit when: Before changing the related capture session behavior.
Why it matters: The day boundary affects how later session history and linkage are read, especially near midnight.
Revisit when: Before changing the related capture session behavior.
Evidence boundary — Reviewed:
Not reviewed:
Run a normal session in a runtime build, then repeat the run with a relay loss and a denied-permission launch. Compare what the player sees on the Watch, what the iPhone reports about connection state, and what the Mac keeps after reconnect. Treat Zepp as supported only after a live path is confirmed.
Reviewed: Reviewed repository snapshot, Founder/owner context
Not reviewed: External runtime and integrations, Unreviewed runtime and owner context
This chapter is about the three-device setup your product needs before a session can reasonably work: the Apple Watch capture app, the iPhone gateway app, and the Mac backend. The Watch asks for workout and heart-rate permission, the iPhone relays batches over a fixed local-network connection, and the Mac side receives and stores the shots.
This chapter is about the three-device setup your product needs before a session can reasonably work: the Apple Watch capture app, the iPhone gateway app, and the Mac backend. The Watch asks for workout and heart-rate permission, the iPhone relays batches over a fixed local-network connection, and the Mac side receives and stores the shots. This is built from the code, so it shows what your product does today, not what you mean it to be, and that part is yours to confirm.
TennisOracle Shot Capture only makes sense as one local chain. The Watch is where capture begins, the iPhone is the relay point, and the Mac backend is where session data lands. That matters because readiness is not something you can judge by looking at just one device. A Watch that opens cleanly but cannot hand off data is not enough, and an iPhone that is ready to relay is not enough if the Mac side is unreachable. The chain is the unit of support, so this chapter treats all three surfaces as one precondition rather than as independent apps.
For the owner, the consequence is simple but important: the question is not whether each device merely exists, but whether they are all present in the same working arrangement at the same time. If any link is missing, the session is not yet a reasonable expectation. A practical example is a player who has the Watch on and the capture view open while the iPhone is nearby but the Mac is asleep or off the reachable network. In that case, the wrist device is not the whole story; the chain is still incomplete.
The reviewed snapshot points to a local-first operating model. The iPhone gateway is configured around a fixed local-network backend address, which means the operator's first question is whether the nearby devices can see one another on the same local network, not whether a remote account has been entered. That changes readiness from a cloud-style login problem into a proximity-and-reachability problem. Power state, Wi-Fi state, and whether the Mac backend is present on the expected local network become part of the setup story.
This is the place where the manual should stay precise about scope. The snapshot shows a local-network operating path; it does not establish the full deployment shape of the product, and it does not prove that no other access path exists elsewhere. So the safe reading is narrower: the supported setup model visible here depends on nearby device state, not on a cloud login flow. If the local path is not healthy, the chain is not ready, even if one device by itself looks fine.
Because no owner-confirmed product intent was supplied, this section stays inside the evidence boundary. It describes the local chain that the current snapshot supports, not the product direction the owner may eventually prefer. That distinction matters because a product that later becomes cloud-mediated, multi-site, or account-centered would need a different readiness model. For now, the manual should teach the owner to think in one frame: Watch capture, iPhone relay, and Mac reception are parts of the same setup condition, and the session is only reasonable when all three line up.
Figure: The owner has to treat readiness as one local chain: the Watch starts capture, the iPhone carries it across the local network, and the Mac must be reachable before the session is truly supported. One device looking ready is not enough.
flowchart LR
W["Watch capture starts on the wrist"]
I["iPhone relay handles the local handoff"]
M["Mac backend must be reachable"]
S["Supported session"]
W --> I --> M
W -.-> S
I -.-> S
M -.-> S
The diagram shows three linked parts: Watch capture on the wrist, the iPhone relay in the middle, and the Mac backend at the end. A supported session only exists when all three are ready together, so checking one device by itself can miss an incomplete setup.
Before capture starts, the system has to clear three different gates. The watch gate is about authorization and getting the workout path started, the iPhone gate is about reaching the Mac backend on the local network, and the relay-loss case is a warning that today’s path does not keep failed traffic around for later. That means readiness is not a single yes or no; it is a chain in which each link can fail differently, and the operator has to check the link that matters at that moment.
| Readiness gate | What must be true | Operator action | If it is not ready |
|---|---|---|---|
| Watch authorization and workout startup | The watch has the required workout and heart-rate authorization, and the workout path has started successfully. | Grant the requested permissions and start the workout path before treating the session as supported. | The rest of the chain is not ready; supported capture should not be assumed available, and the denial behavior itself is not established in the snapshot. |
| iPhone local-network relay | The iPhone can reach the Mac backend on the fixed local network target, and the relay connection is active. | Bring the iPhone and Mac onto the same reachable local network, then connect or reconnect from the iPhone gateway. | The iPhone cannot hand batches to the Mac backend until the relay is reachable. |
| Relay drop during send | The relay link stays up long enough to finish the send, or the operator reconnects before assuming the batch survived. | Reconnect manually after the drop and verify readiness again; do not assume the missed batch will be replayed. | Failed relay traffic can disappear instead of being preserved for later delivery. |
The watch side is a hard precondition because the inspected build asks for workout and heart-rate authorization as part of startup. In practical terms, that makes the watch more than a passive sensor; it is the place where the player either crosses into a supported session or stays outside it. If the authorization gate does not clear, the rest of the chain does not matter yet, because the session has not entered the supported operating path. The one thing the evidence does not establish is what the player sees when permission is denied, so the manual should stop at the boundary: permission failure is blocking, but the denial experience itself remains unverified.
The iPhone is not looking for an arbitrary Mac backend address in this snapshot. It points at one fixed local network target, which means readiness depends on locality and reachability, not on a user-entered destination. For the operator, that changes setup from a general pairing problem into a network-bound check: the iPhone and Mac have to be on a reachable local network, and then the operator uses connect or reconnect to bring the relay up. The consequence is simple. If the backend is not reachable at that fixed local address, the iPhone is not just less ready; it cannot act as the handoff point for watch batches at all. The snapshot does not show a configurable backend address path, so any broader deployment story would need separate confirmation.
The lossy part is the one owners tend to underestimate. In the current path, failed relay sends are not held for later resend, and the watch batch is cleared after the send attempt. Put together, that means a disconnect can erase unsent samples rather than parking them safely until the connection returns. This is not just a backend concern: it changes how the operator interprets a temporary drop during a session. If the relay breaks while the player is still swinging, the safe assumption is that the in-flight batch may be gone, not waiting in a recovery buffer. The only automatic retry described in the reviewed material is a periodic connectivity check once the link has already been established, which is a check on reachability, not a durable resend path. So the practical boundary is strict: reconnect manually, then continue only after readiness is rechecked, because the missed batch may never come back.
For example, if the watch has started and the player hits several shots, but the iPhone loses the Mac backend connection midway through the exchange, the operator cannot treat that gap as temporary storage. The supported path today is restore the relay and continue, not restore the relay and replay what was missed.
Figure: Readiness clears in order, starting with Watch permission and then local reachability, and a mid-send disconnect can lose a batch instead of holding it for later replay. The operator has to think in gates, not a single all-clear signal.
flowchart TD
A["Watch permissions and workout start"]
B["iPhone can reach the Mac"]
C["Batch is being sent"]
D["Relay drops"]
E["Batch may be lost"]
F["Reconnect manually"]
A --> B --> C
C --> D
D --> E
D --> F
F --> B
The diagram shows the setup gates in order: the Watch permissions and workout start first, then the iPhone has to reach the Mac, then a batch can be sent. If the relay drops during send, the batch may be lost, so the operator has to reconnect manually and check readiness again.
The Watch opens into the capture view rather than a passive status screen. In the inspected build, that view gives the player mode selection, a clear Start Oracle / STOP control, and live feedback for speed, readiness, and contact. That matters because it shows the Watch is not just present in the chain; it is the place where the operator-facing capture interaction begins. The boundary is important too: this tells you what the snapshot exposes on screen, not how the whole session should be interpreted or governed. For example, a player can start a capture in one mode, switch to another mode before a drill, and immediately see changing feedback on the Watch without needing to infer whether the device is working.
The iPhone gateway presents the operator with backend status and batch count, plus controls to connect or reconnect. That is a concrete readiness surface, not a hidden background relay: the operator can look at the phone and tell whether the Mac side is currently reachable and whether batches are accumulating. The practical consequence is that the phone is where connection state becomes visible before the player notices a problem on the Watch. The qualifier is that this section only establishes the exposed controls and status readout; it does not establish the full recovery story. In practice, an operator might see the backend status fall out of sync, check the batch count, and use reconnect as the obvious next action instead of guessing whether the relay is alive.
The inspected iPhone client points at one fixed local-network backend address rather than asking the operator to type a destination. That is a narrow but important fact: in this snapshot, the relay path is anchored to a specific local endpoint, so setup depends on that endpoint being the one the client expects. For the owner, the consequence is that the address is not part of ordinary operator configuration in what was inspected; the system is behaving like a preset local gateway, not a user-routed connection target. The limit is equally clear: the snapshot does not show a configurable backend address path, so it does not prove that the product is permanently fixed that way or that no other deployment shape exists elsewhere. A concrete example is an operator bringing up the iPhone at the court and seeing that it is already aimed at the known Mac endpoint, which makes the question "is the backend reachable?" more immediate than "where should I point this phone?".
Figure: The consequence of the loose boundary is exposure: the snapshot shows a fixed local endpoint, but it does not show an access gate or device binding, so any reachable client can touch the write path and create shot records and session events unless another boundary exists outside the snapshot.
flowchart TD
C["Any reachable client"]
subgraph L["Local setup"]
I["iPhone relay"]
B["Mac backend"]
S["Shot records and session events"]
I -->|fixed local address| B
B --> S
end
C -->|can reach the open side| B
The diagram places the iPhone relay and Mac backend inside the local setup, with a reachable client outside it. The iPhone points at one fixed local address, and a client that can reach the open side can connect to the backend. The consequence is that the write path is exposed unless something outside the snapshot adds a stronger boundary.
The strongest part of the current setup story is that it is visible where the operator actually has to act. The Watch presents the capture surface directly, and the iPhone gateway presents its relay state directly. That matters because setup work is not hidden behind a silent background process: the operator can look at the Watch to judge whether the player-side capture surface is alive, and look at the iPhone to judge whether the relay is ready to move batches toward the Mac backend. In practice, that shortens the path from uncertainty to a concrete next step. If something is wrong, the operator is not guessing which device owns the problem; the visible state points them to the right place first.
The Watch permission boundary is also a real strength because it is explicit in both the build and the startup path. The product asks for workout and heart-rate authorization up front, rather than letting the player drift into a session and discover later that capture depended on a missing grant. For an owner, that reduces a common failure mode: the setup requirement is part of the supported path, not an implied background dependency. The boundary is still narrow, though. The evidence establishes that the authorization request exists and that it is part of startup, but it does not establish what denial should look like to the player. So the manual can say the prerequisite is clear; it cannot yet promise a complete denial experience.
The iPhone gateway is similarly strong because it gives the operator immediate feedback about whether the relay is healthy enough to matter. It shows backend status, it shows how many batches are waiting, and it exposes connect and reconnect controls. That combination is useful because it turns readiness into a visible operating condition instead of an invisible one. An operator does not need to assume that watch data is flowing; they can see whether the relay has a backend link, whether data has accumulated, and whether a manual reconnect is the right move. The fixed local-network backend address in this snapshot makes that even more concrete: the relay is not waiting on a user-entered destination, so the operator has fewer moving parts to misconfigure in the moment.
A simple example shows why this is solid. Before a session starts, the Watch can show whether capture is initialized and the iPhone can show whether the Mac backend is reachable. If the Watch is ready but the iPhone still shows a disconnected backend, the operator knows the problem is not on the player’s wrist; it is in the local relay boundary. That is a good owner experience because it makes preflight checks legible without pretending the whole chain is self-healing. The remaining risk is still real: this snapshot does not establish the full deployment shape or guarantee what happens after a disconnect. That belongs with the recovery guidance. Here, the important point is narrower and stronger: the current surfaces already tell the operator where to look before they start.
What happens: The Watch needs authorization, but the reviewed source does not establish the denied-permission experience the owner can rely on.
Why it matters: If denial is not handled clearly, the player can launch the app and still not have a supported session.
What to do: Define the denied-permission message and fallback, then verify that branch on a real Watch.
Revisit when: When setup and preconditions behavior or related owner decisions change.
What happens: The iPhone relay currently points at one hardcoded local backend address, while the intended deployment shape remains unresolved.
Why it matters: A fixed lab machine and a configurable local deployment require different setup instructions and different operator checks.
What to do: Choose one supported topology, document the expected backend address or configuration path, and verify the operator setup against it.
Revisit when: When setup and preconditions behavior or related owner decisions change.
Why it matters: A disconnect can currently cost a batch.
Revisit when: Before changing the related setup and preconditions behavior.
Evidence boundary — Reviewed:
Not reviewed:
Re-run the Watch permission flow on device, confirm what address the iPhone expects the Mac to use, test a dropped local connection, and check whether the backend is meant to be reachable only from trusted devices or from any client on the network.
Reviewed: Reviewed repository snapshot, Founder/owner context
Not reviewed: External runtime and integrations, Unreviewed runtime and owner context
History here is local stewardship. The reviewed material shows the Watch as the capture surface, the Mac side as the place where shot records are kept, and the linkage notes as a separate operator workflow rather than a default part of live capture. For an owner, the key question is whether the records you expect to keep are durable, named consistently, and still trustworthy after interruption.
History here is local stewardship. The reviewed material shows the Watch as the capture surface, the Mac side as the place where shot records are kept, and the linkage notes as a separate operator workflow rather than a default part of live capture. For an owner, the key question is whether the records you expect to keep are durable, named consistently, and still trustworthy after interruption.
That trust is not automatic. The latest-session view is live state, not a durable archive; reconnects create a fresh live session view; and a dropped relay can lose a batch before it becomes history. Session dates also drift between the backend timestamp and the local-date wording in the linkage notes, so any cross-linking rule needs a deliberate owner choice.
Think of this chapter as the owner's map for what history means in TennisOracle. The product keeps the live session moving during capture, writes shot records locally on the Mac side, and treats later linkage as a separate operator step. That separation matters because a live session and a durable record are not the same thing.
The key owner decision is stewardship: what must remain understandable after the session ends. The reviewed material shows that replay is not guaranteed, duplicate shot records can still appear, and the linkage path is only documented as a manual calibration workflow. If the owner wants history to carry real operational weight, the manual has to treat preservation, naming, and date boundaries as product choices rather than background details.
When the player starts capture, the Watch produces batches, the iPhone relays them over the local network, and the Mac side accepts them as shot history. The reviewed relay path is fixed to one local address in this snapshot, so history depends on that local chain staying up long enough to move the batch through.
Once the Mac side accepts a batch, the shot record is written locally and the latest-session view reflects the current live state. That live view is not a durable archive: a new connection starts a fresh session view, and the reviewed relay path does not keep unsent batches for later replay. If Zepp linkage is used at all, it sits outside this live path as a separate manual matching process that compares records by time window and then writes linked session records.
Figure: The owner should treat the local relay chain as the only intended path into history, but not as a protected one. In this snapshot, a reachable client can also reach the history endpoint, and an interrupted relay can erase a batch before it ever becomes stored history.
flowchart TD
subgraph T[Trusted local chain]
W[Watch batches] --> I[iPhone relay]
I --> M[Mac history]
end
A[Reachable client] --> M
I -. dropped relay .-> L[Batch lost]
The figure shows a trusted local chain from Watch batches to the iPhone relay and then to Mac history. It also shows a reachable client feeding the Mac history path directly, and a dropped relay causing a batch to be lost. The consequence is that local history can be both polluted and incomplete unless the owner sets a stronger boundary.
The Watch capture surface is the primary player-facing entry point in the reviewed material.
The Mac side accepts incoming shot batches and writes local shot records without a reviewed access gate.
Shot persistence is a plain write, so duplicate rows remain possible if the same shot is emitted again outside the cooldown window.
The latest-session view returns the current live session only, not a durable historical archive.
The Zepp notes describe a manual calibration workflow, while the date notes show a split between the backend timestamp and local-date wording for linkage.
Figure: Late-day sessions can split across two calendar days if one side uses UTC and the other side uses the local day. The owner needs one rule, or cross-linking and reporting will drift around midnight.
flowchart LR
U[UTC day] --> S[Session tag]
L[Local day] --> N[Linked session note]
S -. different day near midnight .-> N
The figure shows one path that stamps a session tag from the UTC day and another that records linkage using the local day. Near midnight, those two day boundaries can disagree. The consequence is that the same session can appear on different dates unless the rule is normalized.
Figure: Zepp linkage is an operator-side matching flow, not part of live capture. The owner should treat it as a separate calibration path until runtime support is proven.
sequenceDiagram
participant O as Operator
participant Z as Zepp notes
participant M as Mac side
O->>M: open stored session records
O->>Z: match records by time window
O->>M: write linked session record
The figure shows an operator opening stored session records on the Mac side, comparing them with Zepp notes by a time window, and then writing a linked session record. This is separate from live capture because the work happens after the records exist. The consequence is that Zepp should be treated as calibration until live support is confirmed.
This history model does one useful thing well: it keeps the live session, the stored shot records, and the linkage workflow separate enough for an owner to reason about them. That is better than mixing everything into one vague history bucket.
It also leaves the Zepp question visible instead of hiding it. The snapshot shows a manual calibration process, but it does not force the manual to pretend that Zepp is confirmed as a live first-party workflow. The date-boundary drift is also explicit, which is uncomfortable but useful because it prevents silent mismatches around late-day sessions.
What happens: A dropped relay can lose a batch before it becomes history, and repeated emits can still create duplicate rows.
Why it matters: The owner cannot assume every session count or shot count in local history is exact after a disconnect or retry path.
What to do: Decide whether the history path should buffer missed batches and dedupe writes before treating the record store as durable history.
Revisit when: When history and linkage behavior or related owner decisions change.
What happens: The reviewed material shows a manual Zepp calibration process, but not a confirmed live first-party integration.
Why it matters: If operators treat it as supported when it is only documented, they can overstate what the product actually guarantees.
What to do: Decide whether Zepp stays in the supported operator story or moves to appendix-only calibration material.
Revisit when: When history and linkage behavior or related owner decisions change.
Why it matters: The current behavior can drop relay batches and does not restore a durable prior session on reconnect, so the owner must decide whether continuity or best-effort capture is the product promise.
Revisit when: Before changing the related history and linkage behavior.
Why it matters: The current latest-session view is not durable history, so reconnect behavior changes how an owner should read every interrupted run.
Revisit when: Before changing the related history and linkage behavior.
Why it matters: The reviewed connection point accepts any reachable client, so the product needs a deliberate boundary if history is meant to be authoritative.
Revisit when: Before changing the related history and linkage behavior.
Evidence boundary — Reviewed:
Not reviewed:
Run a real session from Watch to iPhone to Mac, then check what remains after a relay loss, a reconnect, and a local midnight boundary. If Zepp is still meant to matter, verify the operator matching flow against a live path before treating it as supported.
Reviewed: Reviewed repository snapshot, Founder/owner context
Not reviewed: External runtime and integrations, Unreviewed runtime and owner context
This chapter is the owner’s line between useful shot feedback and claims the product cannot yet support. The Watch shows speed, readiness, and contact-style feedback during a session, while the Mac turns incoming watch data into the shot-detected event and saved shot records. That is valuable feedback for a player, but the reviewed evidence does not establish calibration approval or validated coaching meaning.
This chapter is the owner’s line between useful shot feedback and claims the product cannot yet support. The Watch shows speed, readiness, and contact-style feedback during a session, while the Mac turns incoming watch data into the shot-detected event and saved shot records.
That is valuable feedback for a player, but the reviewed evidence does not establish calibration approval or validated coaching meaning. Treat the numbers as bounded outputs until a separate review says the thresholds and formulas deserve stronger trust.
Think of the signals as the product’s interpretation layer. The player sees live feedback on the Watch, but the owner should not confuse that reaction with a certified measure of swing quality or fitness.
The named shot event marks the point where the backend decides the incoming motion looks like a shot. Speed, readiness, and contact-style feedback are the player-facing names for that output, but the reviewed evidence does not show that those names carry validated calibration meaning.
During live capture, the Watch gathers motion, the iPhone relays it over the local connection, and the Mac decides whether the data becomes a shot-detected event and a stored shot record. The same path also feeds the player-facing speed, readiness, and contact-style text.
The owner boundary is simple but important: this path is a detector path, not a measurement claim. Readiness is especially narrow here because the current shot path uses a synthetic input, so the number should be read as operational feedback only.
Figure: The intended route runs from the Watch through the iPhone to the Mac, but this snapshot still leaves the Mac open to any reachable client, so shot writes stop being device-bound protection at that boundary.
flowchart TD
subgraph T[Expected capture path]
W[Watch live capture] --> I[iPhone relay] --> M[Mac live connection]
M --> S[Saved shot records]
end
C[Any reachable client] -->|can also connect| M
The Watch sends live capture to the iPhone relay, which passes it to the Mac live connection, and the Mac writes saved shot records. A separate reachable client can also connect to the Mac. The consequence is that the intended relay path exists, but the protection boundary ends at the Mac unless another access control layer is added.
The Watch is the primary player surface, with mode selection, Start Oracle, STOP, live speed, readiness, and contact-style feedback, plus haptics tied to shot-state changes. The iPhone shows backend status, batch count, and connect or reconnect controls, and this snapshot uses a fixed local relay to the Mac backend. The Mac backend accepts incoming data, emits the shot-detected event, and stores shot records.
The same reviewed snapshot shows that readiness is synthetic, the session date can drift between UTC code and local-date documentation, and Zepp appears in the documentation as a manual calibration workflow rather than a confirmed live surface.
Figure: Because the current path starts from synthetic input, the readiness number is operational feedback, not proof of body state or coaching performance.
flowchart LR
subgraph Current[Current shot path]
C1[Synthetic input] --> C2[Readiness number]
end
subgraph Needed[What would support coaching truth]
N1[Measured input] --> N2[Validated signal]
end
C2 -.->|today| N2
On the current shot path, synthetic input produces the readiness number. In the stronger case, a measured input would need validation before the signal could be treated as coaching truth. The consequence is that readiness should stay framed as session feedback until a separate validation review approves it.
The current design is strong on visibility. The player sees live feedback immediately, and the operator can see relay state instead of guessing whether the Mac link is alive.
The second strength is boundary control. The review keeps live capture, calibration interpretation, and later history separate, which gives the owner a clearer line between what the product does now and what still needs validation.
These risks are about trust and meaning, not just completeness. The biggest one is source trust: the backend accepts any reachable client on its live connection and can create shot records and the shot event without a device-bound gate. A second risk is wording: readiness is synthetic in the current path, so it is easy to overstate it as a performance or coaching metric. A third is date drift: the code and the documentation disagree on whether linked sessions follow UTC or local date. Zepp remains provisional as well, because the reviewed material describes a manual calibration workflow but does not establish a confirmed live surface.
This chapter leaves three policy choices open. The first is whether speed, readiness, and contact-style feedback stay framed as session feedback or graduate to stronger coaching language after a separate validation review. The second is whether Zepp stays in the supported story or moves to calibration notes only. The third is whether session tags should follow local date or whether the manual should state the UTC and local split explicitly.
Why it matters: The reviewed evidence shows detector-derived outputs, but not a completed approval story for calibration-grade claims.
Revisit when: Before changing the related signals and calibration behavior.
Evidence boundary — Reviewed:
Not reviewed:
Run a live Watch-to-iPhone-to-Mac session and confirm the player-facing outputs and shot event together. Then verify who is allowed to create shot records on the live connection if that history is meant to stay protected, test a denied-permission device, run a session that crosses local midnight, and repeat any Zepp-linked calibration run only if that path is meant to remain in scope. If the owner wants stronger claims than session feedback, require a separate validation review before using the numbers as coaching truth.
Reviewed: Reviewed repository snapshot, Founder/owner context
Not reviewed: External runtime and integrations, Unreviewed runtime and owner context
TennisOracle only keeps a session alive while the Watch, iPhone gateway, and Mac backend stay in step. The Watch starts the capture flow and shows live feedback, the iPhone relays batches over a fixed local network path, and the Mac backend turns incoming batches into shot records.
TennisOracle only keeps a session alive while the Watch, iPhone gateway, and Mac backend stay in step. The Watch starts the capture flow and shows live feedback, the iPhone relays batches over a fixed local network path, and the Mac backend turns incoming batches into shot records. The operational risk is recovery: failed relay sends are not queued, reconnects create a fresh live session view, and some permission and Zepp boundaries are still not verified. For the owner, this chapter is about deciding which interruptions are acceptable and which need a supported recovery path.
Think of TennisOracle as a fragile local chain, not three independent apps. The Watch is where the player starts capture and sees live feedback. The iPhone is the relay gate. The Mac backend is where shot records and the current live session live. If any link is weak, the product does not automatically guarantee that the session will recover as one continuous record.
Figure: The live path is only as strong as its weakest link. For the owner, that means recovery has to be treated as one chain decision across permission setup, capture, relay, and recording, not as three independent app problems.
flowchart LR
P[Permissions ready] --> W[Watch starts capture]
W --> I[iPhone gateway relays batches]
I --> M[Mac backend records shots]
M --> V[Live session view]
The figure shows a permission gate leading into the Watch, then the iPhone gateway, then the Mac backend, and finally the live session view. The consequence is that a break anywhere in the chain can stop the live session from staying continuous, so recovery has to be designed across the whole path.
Normal operation begins on the Watch after the fitness and workout permissions are available. The player starts a session, the Watch emits motion-based shot feedback, and the iPhone forwards batches to the Mac over the local network. The Mac records the incoming shots and exposes the latest live session view. Recovery is only partially supported in the reviewed snapshot: a missing relay can drop a batch, and a reconnect creates a fresh live session instead of restoring the interrupted one.
Figure: Recovery does not restore the interrupted run. The owner should expect either lost unsent data or a new live view, which means a mid-run break can split the session instead of healing it.
stateDiagram-v2
state "Live session" as Live
state "Relay interrupted" as Break
state "Unsent batch lost" as Lost
state "Fresh live session" as Fresh
[*] --> Live
Live --> Break : relay drops
Break --> Lost : batch is not kept
Break --> Fresh : backend reconnects
Lost --> Fresh
Fresh --> [*]
The figure starts with a live session, then shows a relay interruption. From that interruption, unsent data can be lost, or a backend reconnect can create a fresh live session instead. The consequence is that a break does not reliably restore the same run; it can turn one session into a new one.
The reviewed snapshot confirms these operational facts:
Operationally, the product is easy to explain because each device has one visible job. The Watch is the player-facing surface, the iPhone makes relay state visible to the operator, and the Mac keeps the live session local. The numbers shown on the Watch are framed as feedback from the current shot path, not as a broad promise of sport-science measurement. That clarity is a strength even though it does not solve recovery.
The main operational risk is not one bug; it is that the three-device chain can fail in different ways and the reviewed snapshot does not yet prove a single supported recovery story. The risks below are the ones that can lose batches, split sessions, expose the live connection to unintended clients, or make linked history disagree at the day boundary.
These are the decisions that shape whether recovery can be promised at all. The chapter does not invent the answers; it surfaces them because the reviewed evidence shows that the current behavior or documentation is split.
Evidence boundary — Reviewed:
Not reviewed:
Before promising supported recovery, rerun the Watch start-up path, drop and restore the iPhone-to-Mac connection, reconnect the backend during an active session, and compare the stored session dates and linked history against a live build. If permission or Zepp support matters to the owner, verify those paths on device rather than assuming the snapshot is enough.
Reviewed: Reviewed repository snapshot, Founder/owner context
Not reviewed: External runtime and integrations, Unreviewed runtime and owner context